home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 4 / The Arsenal Files 4 (Arsenal Computer).ISO / casm / au116-as.exe / WHATIS.CPP < prev   
C/C++ Source or Header  |  1994-06-05  |  9KB  |  364 lines

  1. // WHATIS.CPP                                 1          1    6666
  2. // Dave Harris                                11         11   6
  3. // Compiled using Borland C++ ver 3.1       1 1        1 1   6666
  4. // 03-03-94                                  1     ..   1   6   6
  5. //                                           11111 .. 11111  666
  6. ////////////////////////////////////////////////////////////////////////
  7.  
  8. #include "au.hpp"      // Globally used defines
  9.  
  10. /*********************************************************************/
  11. /* Define Statements */
  12. /*********************/
  13.  
  14. #define PROGRAM "WHATIS"  // Name of module
  15.  
  16. /*********************************************************************/
  17. /* Structures */
  18. /**************/
  19.  
  20. typedef struct TYPE
  21. {
  22.     char *desc;
  23.     int  errorlevel;      // errorlevel to return
  24.     BYTE color;
  25.     char nocase;
  26.     unsigned char action[100];
  27. } TYPE;
  28.  
  29. #define START      255     // Goto byte
  30. #define END       254     // Goto byte from end
  31. #define MATCH1      253     // match a byte
  32. #define MATCH2      252     // match a word
  33.  
  34. /*********************************************************************/
  35. /* Global Variables */
  36. /********************/
  37.  
  38. /* Command line/Config options */
  39.  
  40. typedef struct
  41. {
  42.     TYPE *type;
  43.     int type_number;     // current element of type being added to
  44.     int action_pos;
  45.     int errorlevel;
  46. } WHATIS_INFO;
  47.  
  48. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  49. static int process_internal_format(AU *au, ARC_HANDLE *arc_handle,
  50.                                    char *file_name)
  51. {
  52.     int ret_code;
  53.     ARC_RECORD record;
  54.     WHATIS_INFO *in = (WHATIS_INFO *)au->info;
  55.  
  56.     for (EVER)
  57.     {
  58.         ret_code = arc_handle->get_record(au, &record);
  59.         if (ret_code == EOF)
  60.             break;
  61.         else if (ret_code == -2)
  62.         {
  63.             add_to_bad_list(au, au->source_directory, file_name);
  64.             return 0;
  65.         }
  66.         else if (ret_code == -3)
  67.             break;
  68.     }
  69.     au_printf_c(au, au->package[arc_handle->type].whatis_color, "%-*s ",
  70.                 FILE_SIZE, file_name);
  71.     version_print(au, arc_handle->version, 20, TRUE);
  72.     au_printf(au, "\n");
  73.     in->errorlevel = au->package[arc_handle->type].whatis_err;
  74.     arc_handle->deinit(au);
  75.     return 0;
  76. }
  77. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  78. static int whatis(AU *au, char *file_name)
  79. {
  80.     HANDLE handle;
  81.     ARC_HANDLE arc_handle;
  82.     int pos;
  83.     WHATIS_INFO *in = (WHATIS_INFO *)au->info;
  84.  
  85.     au->number_processed++;
  86.     arc_handle.init(au, file_name);
  87.     if (arc_handle.type != 0)
  88.         return process_internal_format(au, &arc_handle, file_name);
  89.     arc_handle.deinit(au);
  90.  
  91.     handle.open(au, file_name);
  92.     for (int i=0; i <= in->type_number; i++)
  93.     {
  94.         pos = 0;
  95.         for(EVER)
  96.         {
  97.             switch(in->type[i].action[pos++])
  98.             {
  99.             case 0:
  100.                 au_printf_c(au, in->type[i].color, "%-*s %s\n", FILE_SIZE,
  101.                             file_name, in->type[i].desc);
  102.                 in->errorlevel = in->type[i].errorlevel;
  103.                 return 0;
  104.             case START:
  105.                 handle.seek(*(long *)(in->type[i].action+pos), SEEK_SET);
  106.                 pos+=4;
  107.                 break;
  108.             case END:
  109.                 handle.seek(*(long *)(in->type[i].action+pos), SEEK_END);
  110.                 pos+=4;
  111.                 break;
  112.             case MATCH1:
  113.             {
  114.                 char ch1 = handle.read_char();
  115.                 char ch2 = in->type[i].action[pos++];
  116.                 if (in->type[i].nocase)
  117.                 {
  118.                     ch1 = toupper(ch1);
  119.                     ch2 = toupper(ch2);
  120.                 }
  121.                 if (ch1 != ch2)
  122.                     goto around;
  123.                 break;
  124.             }
  125.             case MATCH2:
  126.                 break;
  127.             }
  128.         }
  129. around: ;
  130.     }
  131.     handle.close();
  132.     au_printf_c(au, 7, "%-*s other\n", FILE_SIZE, file_name);
  133.     return 0;
  134. }
  135. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  136. static long read_number(AU *au, char *string, CFG_HANDLE *cfg_handle)
  137. {
  138.     long number=0;
  139.     int  pos=0;
  140.     int  negate = FALSE;
  141.     int  i;
  142.  
  143.     if (string[0]=='-')
  144.     {
  145.         negate = TRUE;
  146.         pos = 1;
  147.     }
  148.     if (string[pos]=='0')
  149.     {
  150.         if (toupper(string[pos+1]) == 'X')    // Hex
  151.         {
  152.             for (i=pos+2; i<strlen(string); i++)
  153.             {
  154.                 string[i] = toupper(string[i]);
  155.                 number*=16;
  156.                 if (string[i]>='A' && string[i]<='F')
  157.                     number+=string[i]-'A'+10;
  158.                 else if (string[i]>='0' && string[i]<='9')
  159.                     number+=string[i]-'0';
  160.                 else
  161.                     cfg_handle->invalid(au, "Bad hex constant");
  162.             }
  163.         }
  164.         else                                         // Octal
  165.         {
  166.             for (i=pos+1; i<strlen(string); i++)
  167.             {
  168.                 number*=8;
  169.                 if (string[i]>='0' && string[i]<='7')
  170.                     number+=string[i]-'0';
  171.                 else
  172.                     cfg_handle->invalid(au, "Bad octal constant");
  173.             }
  174.         }
  175.     }
  176.     else                                            // Decimal
  177.     {
  178.         for (i=pos; i<strlen(string); i++)
  179.         {
  180.             number*=10;
  181.             if (string[i]>='0' && string[i]<='9')
  182.                 number+=string[i]-'0';
  183.             else
  184.                 cfg_handle->invalid(au, "Bad decimal constant");
  185.         }
  186.     }
  187.     if (negate)
  188.         return -number;
  189.     else
  190.         return number;
  191. }
  192. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  193. static void ReadCFGInfo(AU *au, CFG_HANDLE *cfg_handle)
  194. {
  195.    char string[200],
  196.         string2[200],
  197.         string3[200];
  198.  
  199.    int len;
  200.    int i;
  201.    WHATIS_INFO *in = (WHATIS_INFO *)au->info;
  202.  
  203.    for(EVER)
  204.    {
  205.       if (cfg_handle->read_line(au, string)==EOF)
  206.          break;
  207.  
  208. /////////////////////////////////////////
  209. around:
  210.       ltrim(string);
  211.       if (string[0] == '\0')
  212.          continue;
  213.  
  214.       if (string[0] == '\"')
  215.       {
  216.          len = strlen(string);
  217.          string[0] = ' ';
  218.          for (i=1; i<len; i++)
  219.          {
  220.             if (string[i]=='\"')
  221.             {
  222.                string[i] = ' ';
  223.                goto around;
  224.             }
  225.             in->type[in->type_number].action[in->action_pos++] = MATCH1;
  226.             in->type[in->type_number].action[in->action_pos++] = string[i];
  227.             string[i] = ' ';  // so ltrim will hack it off
  228.          }
  229.          cfg_handle->invalid(au, "\" missing");
  230.       }
  231.  
  232.       split_string(string, string2);
  233.       switch (toupper(string2[1]) << 8 | toupper(string2[0]))
  234.       {
  235.          case 'BE':                                          // Begin
  236.             return;
  237.          case 'TY':                                          // Type
  238.          {
  239.             int len,i;
  240.  
  241.             in->type_number++;
  242.             in->action_pos = 0;
  243.             in->type[in->type_number].color = 7;
  244.             if (string[0]!='\"')
  245.                cfg_handle->invalid(au, "\" missing");
  246.             string[0]=' ';
  247.             len=strlen(string);
  248.             for (i=1 ; i<len ; i++)
  249.             {
  250.                if (string[i]=='\"')
  251.                {
  252.                   string[i] = ' ';
  253.                   goto bp1;
  254.                }
  255.                string2[i-1] = string[i];
  256.                string[i] = ' ';
  257.             }
  258.             cfg_handle->invalid(au, "\" missing");
  259. bp1:
  260.             string2[i-1] = '\0';
  261.             in->type[in->type_number].desc =
  262.                       (char *)au_malloc(au, strlen(string2)+1);
  263.             strcpy(in->type[in->type_number].desc,string2);
  264.             goto around;
  265.          }
  266.          case 'ST':
  267.             split_string(string, string2);
  268.             in->type[in->type_number].action[in->action_pos++] = START;
  269.             *(long *)(in->type[in->type_number].action+in->action_pos) =
  270.                 read_number(au, string2, cfg_handle);
  271.             in->action_pos+=4;
  272.             goto around;
  273.          case 'EN':
  274.             split_string(string, string2);
  275.             in->type[in->type_number].action[in->action_pos++] = END;
  276.             *(long *)(in->type[in->type_number].action+in->action_pos) =
  277.                 read_number(au, string2, cfg_handle);
  278.             in->action_pos+=4;
  279.             goto around;
  280.          case 'ER':
  281.             split_string(string, string2);
  282.             in->type[in->type_number].errorlevel =
  283.                 read_number(au, string2, cfg_handle);
  284.             goto around;
  285.          case 'CO':
  286.             split_string(string, string2);
  287.             in->type[in->type_number].color =
  288.                 read_number(au, string2, cfg_handle) % 16;
  289.             goto around;
  290.          case 'NO':
  291.             in->type[in->type_number].nocase = TRUE;
  292.             goto around;
  293.          default:                 /* number of some sort probably */
  294.          {
  295.             long number;
  296.  
  297.             number = read_number(au, string2, cfg_handle);
  298.             if (number <= 255)
  299.             {
  300.                in->type[in->type_number].action[in->action_pos++] = MATCH1;
  301.                in->type[in->type_number].action[in->action_pos++] = number;
  302.             }
  303.             else
  304.             {
  305.                in->type[in->type_number].action[in->action_pos++] = MATCH2;
  306.                *(int *)(in->type[in->type_number].action[in->action_pos+=2]) = number;
  307.             }
  308.             goto around;
  309.          }           /* End Default */
  310.       }         /* End Switch */
  311.    }         /* End For */
  312. }
  313. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  314. static BYTE parse_comm_line(AU *au, char option, char *, PARSE_TYPE type)
  315. {
  316.     switch (type)
  317.     {
  318.     case PARSE_PARAM_OPTION:
  319.         switch (option)
  320.         {
  321.         case '?':
  322.             au_standard_opt_header(au, "Whatis", NULL);
  323.             exit (0);
  324.         default:
  325.             au_invalid_option(au, PROGRAM, option);
  326.         }
  327.         return TRUE;
  328.     }
  329.     return FALSE;
  330. }
  331. /*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
  332. int main_whatis(AU *au, int argc, char *argv[])
  333. {
  334.     int retCode;
  335.     WHATIS_INFO *in;
  336.  
  337.     in = (WHATIS_INFO *)au_malloc(au, sizeof(WHATIS_INFO));
  338.     memset(in, '\0', sizeof(WHATIS_INFO));
  339.     au->info = in;
  340.  
  341.     in->type = (TYPE *)au_malloc(au, sizeof(TYPE)*200);
  342.     if (in->type == NULL)
  343.     {
  344.         au_printf_error(au, "Out of Memory\n");
  345.         exit(1);
  346.     }
  347.     in->type_number = -1;
  348.  
  349.     ReadGlobalCFGInfo(au, au->cfg_file, PROGRAM, ReadCFGInfo);
  350.     generic_parse_comm_line(au, argc, argv, parse_comm_line);
  351.     process_files(au, whatis);
  352.  
  353.     if (!au->no_extra)
  354.     {
  355.         au_printf_c(au, 15, "\nFiles Processed = %d\n", au->number_processed);
  356.         au_printf_c(au, 15, "Exiting with errorlevel %d\n", in->errorlevel);
  357.     }
  358.  
  359.     retCode = in->errorlevel;
  360.     free(in->type);
  361.     return retCode;
  362. }
  363.  
  364.